package it.bela.pgcdc.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import it.bela.pgcdc.common.utils.Constants;
import it.bela.pgcdc.domain.Attivita;
import it.bela.pgcdc.domain.Contatto;
import it.bela.pgcdc.domain.Hobby;
import it.bela.pgcdc.domain.MailingList;
import it.bela.pgcdc.domain.Preferenza;
import it.bela.pgcdc.domain.vo.InviaMail;
import it.bela.pgcdc.editor.AttivitaPropertyEditor;
import it.bela.pgcdc.editor.HobbyPropertyEditor;
import it.bela.pgcdc.editor.MaililngListPropertyEditor;
import it.bela.pgcdc.editor.PreferenzaPropertyEditor;
import it.bela.pgcdc.service.AttivitaService;
import it.bela.pgcdc.service.ContattoService;
import it.bela.pgcdc.service.HobbyService;
import it.bela.pgcdc.service.MailingListService;
import it.bela.pgcdc.service.PreferenzaService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

@Controller
public class HomeController {

	private static final Logger log = Logger.getLogger(HomeController.class);
	
	@Autowired(required = true)
	private ContattoService contattoService;
	
	@Autowired(required = true)
	private PreferenzaService preferenzaService;
	
	@Autowired(required = true)
	private AttivitaService attivitaService;
	
	@Autowired(required = true)
	private HobbyService hobbyService;
	
	@Autowired(required = true)
	private MailingListService mailingListService;
	
	@Autowired
	private transient MailSender mailSender;
	
	@ModelAttribute("preferenzaList")
	public List<Preferenza> populatePreferenzaList() throws Exception {
		try{

			List<Preferenza> preferenzaList = preferenzaService.list();
			return preferenzaList;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione Contatto - " + e);
			throw new Exception(Constants.POPULATE_MODEL_ERROR_KEY, e);
		}
	}
	
	@ModelAttribute("attivitaList")
	public List<Attivita> populateAttivitaList() throws Exception {
		try{

			List<Attivita> attivitaList = attivitaService.list();
			return attivitaList;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione Contatto - " + e);
			throw new Exception(Constants.POPULATE_MODEL_ERROR_KEY, e);
		}
	}
	
	@ModelAttribute("hobbyList")
	public List<Hobby> populatHobbyList() throws Exception {
		try{

			List<Hobby> hobbyList = hobbyService.list();
			return hobbyList;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione Contatto - " + e);
			throw new Exception(Constants.POPULATE_MODEL_ERROR_KEY, e);
		}
	}
	
	@ModelAttribute("inviaMail")
	public InviaMail populatInviaMail() throws Exception {
		try{
			
			InviaMail inviaMail = new InviaMail();
			
			inviaMail.setSendToList(contattoService.list());
			
			return inviaMail;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione Contatto - " + e);
			throw new Exception(Constants.POPULATE_MODEL_ERROR_KEY, e);
		}
	}
	
	@ModelAttribute("mailingListList")
	public List<MailingList> populatMailingListList() throws Exception {
		try{

			List<MailingList> mailingListList = mailingListService.list();
			return mailingListList;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione Contatto - " + e);
			throw new Exception(Constants.POPULATE_MODEL_ERROR_KEY, e);
		}
	}
	
	@ModelAttribute("contattoList")
	public List<Contatto> populateContattoList() throws Exception {
		try{

			List<Contatto> contattoList = contattoService.list();

			return contattoList;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione home - " + e);
			throw new Exception(Constants.HOME_VIEW_ERROR_KEY, e);
		}
	}
	
	@ModelAttribute("contatto")
	public Contatto populateContatto() throws Exception {
		try{

			return new Contatto();
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione home - " + e);
			throw new Exception(Constants.HOME_VIEW_ERROR_KEY, e);
		}
	}

	@RequestMapping("home.htm")
	public ModelAndView home(HttpServletRequest request, HttpServletResponse response) throws Exception {

		try{
			
			log.debug("Start view home");

			ModelAndView mav = new ModelAndView(Constants.HOME_TILES_KEY_HOME);
			
			log.debug("End view home");
			
			return mav;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione home - " + e);
			throw new Exception(Constants.HOME_VIEW_ERROR_KEY, e);
		}
	}
	
	@RequestMapping(value = "searchContatti.htm", method = RequestMethod.POST)
	public ModelAndView searchContatti(@ModelAttribute("contatto") Contatto contatto,
			BindingResult errors, SessionStatus status, HttpServletRequest request, HttpServletResponse res) throws Exception {

		try{
			
			log.debug("Start view searchContatti");

			ModelAndView mav = new ModelAndView(Constants.HOME_TILES_KEY_HOME);
			
			InviaMail inviaMail = new InviaMail();
			inviaMail.setSendToList(contattoService.findByExample(contatto));
			
			mav.addObject("inviaMail", inviaMail);
			
			log.debug("End view searchContatti");
			
			return mav;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione home - " + e);
			throw new Exception(Constants.HOME_VIEW_ERROR_KEY, e);
		}
	}
	
	@RequestMapping(value = "inviaMail.htm", method = RequestMethod.POST)
	public ModelAndView inviaMail(@ModelAttribute("inviaMail") InviaMail inviaMail,
			BindingResult errors, SessionStatus status, HttpServletRequest request, HttpServletResponse res) throws Exception {

		try{
			
			log.debug("Start view inviaMail");

			ModelAndView mav = new ModelAndView(Constants.HOME_TILES_KEY_HOME);
			
			if (inviaMail.getSendToList() != null && !inviaMail.getSendToList().isEmpty()){
				
				String[] mailTo;
				List<String> mailToList = new ArrayList<String>();
				
				for (Contatto contatto : inviaMail.getSendToList()) {
					
					if (contatto.isSendTo() && contatto.getEmail() != null && !contatto.getEmail().equals("")){
						mailToList.add(contatto.getEmail());
					}
				}
				
				mailTo = new String[mailToList.size()];
				
				sendMessage("sencdc@sentinelle.it", inviaMail.getOggetto(), mailToList.toArray(mailTo), inviaMail.getTesto());
			}
			
			mav.addObject("inviaMail", inviaMail);
			
			log.debug("End view inviaMail");
			
			return mav;
		}
		catch (Exception e) {
			e.printStackTrace();
			log.error("view - Errore durante la visualizzazione home - " + e);
			throw new Exception(Constants.HOME_VIEW_ERROR_KEY, e);
		}
	}
	
	@InitBinder
	public void initBinder(WebDataBinder binder) {

		CustomDateEditor editorDate = new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy", LocaleContextHolder.getLocale()), true);	
		binder.registerCustomEditor(Date.class, editorDate);
		
		PreferenzaPropertyEditor preferenzaPropertyEditor = new PreferenzaPropertyEditor(preferenzaService);
		binder.registerCustomEditor(Preferenza.class, preferenzaPropertyEditor);
		
		AttivitaPropertyEditor attivitaPropertyEditor = new AttivitaPropertyEditor(attivitaService);
		binder.registerCustomEditor(Attivita.class, attivitaPropertyEditor);
		
		HobbyPropertyEditor hobbyPropertyEditor = new HobbyPropertyEditor(hobbyService);
		binder.registerCustomEditor(Hobby.class, hobbyPropertyEditor);
		
		MaililngListPropertyEditor maililngListPropertyEditor = new MaililngListPropertyEditor(mailingListService);
		binder.registerCustomEditor(MailingList.class, maililngListPropertyEditor);
	}
	
	private void sendMessage(final String mailFrom, final String subject, final String[] mailTo, final String message) {
		SimpleMailMessage mailMessage = new SimpleMailMessage();
		mailMessage.setFrom(mailFrom);
		mailMessage.setSubject(subject);
		mailMessage.setTo(mailTo);
		mailMessage.setText(message);
		mailSender.send(mailMessage);
		
//		MimeMessagePreparator preparator = new MimeMessagePreparator() {
//            public void prepare(MimeMessage mimeMessage) throws Exception {
//               MimeMessageHelper mailMessage = new MimeMessageHelper(mimeMessage);
//               mailMessage.setTo(mailTo);
//               mailMessage.setFrom(mailFrom);
//               mailMessage.setSubject(subject);
//               mailMessage.setText(message, true); //true means enable html email
//            }
//         };
	}
}
